package replay

import (
	"context"
	"io"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"
)

// MultiFilePlayer 用于回放多个文件，基于Player实现
type MultiFilePlayer struct {
	paths          []string // 按顺序排列的文件路径
	current        int      // 当前处理的文件索引
	player         *Player  // 当前使用的Player实例
	speed          float64
	mu             sync.RWMutex
	protocolPrefix []byte // 协议前缀
}

// NewMultiFilePlayer 创建多文件播放器，支持通配符路径
func NewMultiFilePlayer(pattern string) (*MultiFilePlayer, error) {
	paths, err := filepath.Glob(pattern)
	if err != nil {
		return nil, err
	}

	// 按文件名排序
	sort.Slice(paths, func(i, j int) bool {
		return compareFilePaths(paths[i], paths[j])
	})

	return &MultiFilePlayer{
		paths: paths,
		speed: 1,
	}, nil
}

// compareFilePaths 比较两个文件路径，按照数字顺序排序
func compareFilePaths(a, b string) bool {
	// 提取文件名（不含扩展名）
	nameA := strings.TrimSuffix(filepath.Base(a), filepath.Ext(a))
	nameB := strings.TrimSuffix(filepath.Base(b), filepath.Ext(b))

	// 尝试解析为数字
	numA, errA := strconv.Atoi(nameA)
	numB, errB := strconv.Atoi(nameB)

	// 如果都是数字，按数字大小比较
	if errA == nil && errB == nil {
		return numA < numB
	}

	// 如果都不是数字，按字典序比较
	if errA != nil && errB != nil {
		return nameA < nameB
	}

	// 数字文件名优先于非数字文件名
	if errA == nil {
		return true
	}
	return false
}

// SetProtocolPrefix 设置协议前缀
func (p *MultiFilePlayer) SetProtocolPrefix(prefix []byte) {
	p.mu.Lock()
	defer p.mu.Unlock()
	p.protocolPrefix = make([]byte, len(prefix))
	copy(p.protocolPrefix, prefix)

	// 如果当前有player实例，也设置其协议前缀
	if p.player != nil {
		p.player.SetProtocolPrefix(prefix)
	}
}

// SetSpeed 动态调整回放倍数
func (p *MultiFilePlayer) SetSpeed(s float64) {
	p.mu.Lock()
	p.speed = s
	p.mu.Unlock()

	// 如果当前有player实例，也设置其速度
	if p.player != nil {
		p.player.SetSpeed(s)
	}
}

// Replay 按记录时间间隔回放，支持倍数；ctx 可随时取消
func (p *MultiFilePlayer) Replay(ctx context.Context, onData func(ts time.Time, data []byte)) error {
	for p.current < len(p.paths) {
		select {
		case <-ctx.Done():
			if p.player != nil {
				p.player.Close()
			}
			return ctx.Err()
		default:
		}

		// 创建当前文件的Player
		player, err := NewPlayer(p.paths[p.current])
		if err != nil {
			return err
		}

		// 设置协议前缀和速度
		if len(p.protocolPrefix) > 0 {
			player.SetProtocolPrefix(p.protocolPrefix)
		}
		player.SetSpeed(p.speed)

		// 使用当前player回放文件
		err = player.Replay(ctx, onData)

		// 关闭当前player
		player.Close()

		if err != nil && err != io.EOF {
			return err
		}

		// 移动到下一个文件
		p.current++
	}

	return nil
}

// Close 关闭当前player（如果有的话）
func (p *MultiFilePlayer) Close() error {
	if p.player != nil {
		return p.player.Close()
	}
	return nil
}

// GetPaths 返回当前加载的文件路径列表
func (p *MultiFilePlayer) GetPaths() []string {
	paths := make([]string, len(p.paths))
	copy(paths, p.paths)
	return paths
}

// GetTotalFiles 返回总文件数量
func (p *MultiFilePlayer) GetTotalFiles() int {
	return len(p.paths)
}

// GetCurrentFileIndex 返回当前处理的文件索引
func (p *MultiFilePlayer) GetCurrentFileIndex() int {
	return p.current
}

// GetCurrentFilePath 返回当前处理的文件路径
func (p *MultiFilePlayer) GetCurrentFilePath() string {
	if p.current < len(p.paths) {
		return p.paths[p.current]
	}
	return ""
}
